home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Crypto⁄Encryption / Premium (CANAL+) decoder / nagra / nagra.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-05  |  15.9 KB  |  542 lines  |  [TEXT/MMCC]

  1. /* The values key_start & key_inc are searched by correlation on a few
  2.  * lines & columns of the frame. Please read the licence in the README
  3.  * file before using this code.  */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <assert.h>
  9.  
  10. #include "nagra.h"
  11.  
  12. #define KEY_BUF_SIZE 25
  13. int key_locked;
  14. int key_buf_ptr=0;
  15. int key_buf[KEY_BUF_SIZE];
  16.  
  17. char table_keys[256] = {
  18. 0,1,2,3,4,5,6,7,2,5,4,7,8,9,10,11,14,17,16,19,22,
  19. 25,24,27,28,31,30,1,24,27,26,29,8,11,10,13,20,23,
  20. 22,25,20,21,22,23,30,31,0,1,16,17,18,19,28,29,30,
  21. 31,10,11,12,13,16,17,18,19,12,15,14,17,0,1,2,3,20,
  22. 23,22,25,18,19,20,21,22,25,24,27,26,27,28,29,18,
  23. 21,20,23,10,13,12,15,28,29,30,31,4,5,6,7,22,23,24,
  24. 25,4,7,6,9,30,1,0,3,26,29,28,31,2,5,4,7,8,9,10,11,
  25. 14,15,16,17,24,27,26,29,14,17,16,19,6,9,8,11,16,
  26. 19,18,21,28,31,30,1,24,25,26,27,20,21,22,23,0,3,2,
  27. 5,6,7,8,9,12,13,14,15,8,11,10,13,2,3,4,5,30,31,0,
  28. 1,24,25,26,27,2,3,4,5,30,1,0,3,6,9,8,11,12,15,14,
  29. 17,26,27,28,29,14,15,16,17,18,19,20,21,22,23,24,
  30. 25,4,7,6,9,18,21,20,23,12,13,14,15,16,19,18,21,26,
  31. 29,28,31,10,11,12,13,10,13,12,15,6,7,8,9,0,3,2,5
  32. };
  33.  
  34.  
  35. /* #define PROFILE */
  36.  
  37. /* define it to use the asm version */
  38.  
  39. int bars=0;
  40.  
  41. #define NB_KEYS  32768
  42.  
  43. /* Number of pixels per line on which the correlation is achieved.
  44.    must be a multiple of 8 */ 
  45. #define CX_COUNT 24
  46.  
  47. /* Number of couples of lines on which the correlation is
  48.    achieved. You must modify it in the asm source too */
  49. #define NB_COUPLES 16
  50.  
  51. /* The correlation use only the lines after LINE_MIN */
  52. /*#define LINE_MIN 96*/
  53. #define LINE_MIN 96
  54.  
  55. /* The correlation use only the lines before LINE_MAX */
  56. #define LINE_MAX (286-96)
  57.  
  58. unsigned short key_lines[NB_KEYS][NB_COUPLES];
  59. unsigned int couple_index[6000];
  60. int couple_index_nb;
  61. unsigned short correl_lines[6000];
  62.  
  63. static unsigned char rgb_to_y[32768];
  64.  
  65. /* init variables */
  66. int nb_couples;
  67.  
  68. int *couple_next;
  69. int *couple_first;
  70. int *couple_score;
  71. int *couple_nb;
  72.  
  73. void decode_frame(unsigned char *dest,int dest_xsize,
  74.         unsigned char **lines,int xsize,int ysize,
  75.         int gray_scale,int full_pal, int g32bit)
  76. {
  77.     int y,x,format,xsize1;
  78.     unsigned short perm[287];
  79.     register short *p2;
  80.     register unsigned char *p1;
  81.     unsigned char *pc;
  82.     unsigned int t1, t2;
  83.     int diff;
  84.     int decode;
  85.  
  86.     if (gray_scale) xsize1=xsize; else xsize1=2*xsize;
  87.  
  88.  
  89.     /* find the permutation  */
  90.     format = 0;    /* 15 bit */
  91.     if (g32bit) format = 1;
  92.  
  93.     decode = decode_nagra(perm,(void **)lines,xsize,format);
  94.  
  95.     /* do the permutation */
  96.     if (!full_pal)
  97.     {
  98.       if (format == 0)
  99.       {
  100.         p2 = (short *) dest+bars*dest_xsize;;
  101.         for (y = bars; y < YSIZE-bars; y++)
  102.         {
  103.         p1 = lines[y];
  104.         if (decode==0) p1 = lines[perm[y]];
  105.         for (x = 0; x < (384/2); x++)
  106.         {
  107.             ((unsigned int *) p2)[0] = ((unsigned int *) p1)[0];
  108.             p2 += 2;
  109.             p1 += 4;
  110.         }
  111.         p2 += dest_xsize - 384;
  112.         }
  113.       } else { /* format: 32 bit digitized */
  114.         p2 = (short *) dest+bars*dest_xsize;;
  115.         for (y = bars; y < YSIZE-bars; y++)
  116.         {
  117.         p1 = lines[y];
  118.         if (decode==0) p1 = lines[perm[y]];
  119.  
  120.         for (x = 0; x < (384/2); x++)
  121.         {
  122.             ((unsigned int *) p2)[0] =         ((p1[1]<<(7+16))&0x7c000000)
  123.                                         |    ((p1[2]<<(2+16))&0x03e00000)
  124.                                         |    ((p1[3]<<13)&0x001f0000)
  125.                                         |    ((p1[5]<<7)&0x7c00)
  126.                                         |    ((p1[6]<<2)&0x03e0)
  127.                                         |    ((p1[3]>>3)&0x001f);
  128.             p2 += 2;
  129.             p1 += 8;
  130.         }
  131.         p2 += dest_xsize - 384;
  132.         }
  133.       }
  134.     } else {
  135.         p2 = (short *) dest+bars*dest_xsize;
  136.         for (y = bars; y < YSIZE-bars; y++)
  137.         {
  138.         p1 = lines[y];
  139.         if (decode==0) p1 = lines[perm[y]];
  140.         for (x = 0; x < (384/2); x++)
  141.         {
  142.             ((unsigned int *) p2)[0] = ((unsigned short *) p1)[0] | (((unsigned short *) p1)[0]<<16);
  143.             ((unsigned int *) (p2+dest_xsize))[0] = ((unsigned short *) p1)[0] | (((unsigned short *) p1)[0]<<16);
  144.             ((unsigned int *) p2)[1] = ((unsigned short *) p1)[1] | (((unsigned short *) p1)[1]<<16);
  145.             ((unsigned int *) (p2+dest_xsize))[1] = ((unsigned short *) p1)[1] | (((unsigned short *) p1)[1]<<16);
  146.             p2 += 4;
  147.             p1 += 4;
  148.         }
  149.         p2 += dest_xsize - 384*2;
  150.         p2 += dest_xsize;
  151.         }
  152.     }
  153. }
  154.  
  155. /* compute the permutation generated by the 15 bit key 'key' */
  156. static void gen_perm(unsigned short *perm,int key)
  157. {
  158.   int key_start,key_inc,key_index,i,b;
  159.   int buffer[32];
  160.  
  161.   key_start=key >> 7;
  162.   key_inc=(key & 0x7f)*2+1;
  163.  
  164.   for(i=0;i<32;i++) buffer[i]=i;
  165.  
  166.   key_index=key_start;
  167.   for(i=0;i<255;i++) {
  168.     b=table_keys[key_index];
  169.     perm[i]=buffer[b];
  170.     buffer[b]=i+32;
  171.  
  172.     key_index=(key_index+key_inc) & 0xff;
  173.   }
  174.  
  175.   for(i=0;i<32;i++) {
  176.     perm[255+i]=buffer[i];
  177.   }
  178. }
  179.  
  180.  
  181. void add_couple(int c)
  182. {
  183.   int p,key,q,y1,y2,nb;
  184.  
  185.   y1=c / YSIZE;
  186.   y2=c % YSIZE;
  187.   couple_index[couple_index_nb]=(y1 << 9) | y2;
  188.  
  189.   p=couple_first[c];
  190.   while (p!=-1) {
  191.     key=p / nb_couples;
  192.     nb=couple_nb[key]++;
  193.     q=couple_next[p];
  194.     if (nb < NB_COUPLES) {
  195.       key_lines[key][nb]=couple_index_nb*2;
  196.     }
  197.     p=q;
  198.   }
  199.   couple_index_nb++;
  200. }
  201.  
  202. int score_couple(int c)
  203. {
  204.   int p,key,score;
  205.  
  206.   score=0;
  207.   p=couple_first[c];
  208.   while (p!=-1) {
  209.     key=p / nb_couples;
  210.     if (couple_nb[key] < NB_COUPLES) score++;
  211.     p=couple_next[p];
  212.   }
  213.   return score;
  214. }
  215.  
  216.  
  217. static void init_decode_tables(void)
  218. {
  219.   int key,i,j,last_y,y,p,q,score;
  220.   unsigned short perm[YSIZE];
  221.   int nb_tot,score_max;
  222.   int line_min=LINE_MIN,line_max=LINE_MAX;
  223.  
  224.   nb_couples=line_max-line_min;
  225.  
  226.   couple_next=malloc(sizeof(int)*nb_couples*NB_KEYS);
  227.   couple_first=malloc(YSIZE*YSIZE*sizeof(int));
  228.   couple_score=malloc(YSIZE*YSIZE*sizeof(int));
  229.   couple_nb=malloc(NB_KEYS*sizeof(int));
  230.  
  231.   for(i=0;i<YSIZE*YSIZE;i++) couple_first[i]=-1;
  232.   for(i=0;i<YSIZE*YSIZE;i++) couple_score[i]=0;
  233.  
  234.   for(key=0;key<NB_KEYS;key++) {
  235.     gen_perm(perm,key);
  236.  
  237.     last_y=perm[line_min];
  238.     for(i=line_min+1;i<=line_max;i++) {
  239.       y=perm[i];
  240.       if (y < last_y) j=y*YSIZE+last_y; else j=last_y*YSIZE+y;
  241.       last_y=y;
  242.  
  243.       q=(key*nb_couples)+i-(line_min+1);
  244.       p=couple_first[j];
  245.       couple_next[q]=p;
  246.       couple_first[j]=q;
  247.       couple_score[j]++;
  248.     }
  249.  
  250.   }
  251.  
  252.   for(i=0;i<NB_KEYS;i++) couple_nb[i]=0;
  253.  
  254.   nb_tot=0;
  255.   couple_index_nb=0;
  256.   do {
  257.     score_max=0;
  258.     j=0;
  259.     for(i=0;i<YSIZE*YSIZE;i++) {
  260.       if (couple_score[i] > score_max) {
  261.         score_max=couple_score[i];
  262.         j=i;
  263.       }
  264.     }
  265.     score=score_couple(j);
  266.     if (score > 0) {
  267.       nb_tot+=score;
  268.       add_couple(j);
  269.     }
  270.     couple_score[j]=0;
  271.   } while (nb_tot < (NB_KEYS*NB_COUPLES)) ;
  272.  
  273.   free(couple_nb);
  274.   free(couple_score);
  275.   free(couple_first);
  276.   free(couple_next);
  277.  
  278. }
  279.  
  280. void init_decode_nagra(void)
  281. {
  282.   int i;
  283.   
  284. /*  memcpy(table_keys,table,256); */
  285.  
  286.   init_decode_tables();
  287.  
  288.   /* we precompute the table for rgb_to_y conversion */
  289.   for(i=0;i<32768;i++) {
  290.     int r,g,b,y;
  291.  
  292.     r=(i >> 10) << 3;
  293.     g=((i >> 5) & 0x1f) << 3;
  294.     b=(i & 0x1f) << 3;
  295.     y=(int)(77.0 * r + 150.0 * g + 29.0 * b + 128.0) >> 8;
  296.     if (y>255) y=255;
  297.     rgb_to_y[i]=y;
  298.   }
  299. }
  300.  
  301. /* asm version for NB_COUPLES == 12 or 10 (see try_perm.S for the x86 asm version) */
  302. unsigned short *try_perm1(void);
  303.  
  304. /*
  305.  * C version of try_perm 
  306.  */
  307. unsigned short *try_perm(void)
  308. {
  309.   int corr_min;
  310.   unsigned short *key_end,*key_min;
  311.   register unsigned short *key_ptr;
  312.   register int corr;
  313.  
  314.   corr_min=0x7fffffff;
  315.   key_min=NULL;
  316.   key_ptr=(unsigned short *)key_lines;
  317.   key_end=key_ptr+NB_KEYS*NB_COUPLES;
  318.  
  319.   /* fast correlation on a few lines */
  320.   do {
  321.  
  322.     corr=0;
  323. #if NB_COUPLES == 12
  324.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
  325.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
  326.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
  327.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
  328.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
  329.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
  330.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
  331.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
  332.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
  333.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
  334.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
  335.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
  336. #elif NB_COUPLES == 10
  337.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
  338.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
  339.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
  340.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
  341.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
  342.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
  343.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
  344.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
  345.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
  346.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
  347. #elif NB_COUPLES == 8
  348.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
  349.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
  350.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
  351.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
  352.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
  353.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
  354.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
  355.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
  356. #elif NB_COUPLES == 16
  357.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
  358.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
  359.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
  360.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
  361.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
  362.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
  363.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
  364.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
  365.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
  366.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
  367.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
  368.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
  369.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[12]);
  370.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[13]);
  371.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[14]);
  372.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[15]);
  373. #elif NB_COUPLES == 24
  374.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
  375.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
  376.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
  377.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
  378.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
  379.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
  380.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
  381.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
  382.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
  383.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
  384.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
  385.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
  386.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[12]);
  387.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[13]);
  388.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[14]);
  389.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[15]);
  390.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[16]);
  391.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[17]);
  392.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[18]);
  393.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[19]);
  394.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[20]);
  395.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[21]);
  396.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[22]);
  397.     corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[23]);
  398. #else
  399.     { 
  400.       int j,c;
  401.       for(j=0;j<NB_COUPLES;j++) {
  402.         c=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[j]);
  403.         corr+=c;
  404.       }
  405.     }
  406. #endif
  407.  
  408.     key_ptr+=NB_COUPLES;
  409.  
  410.     /* test correlation */
  411.     if (corr < corr_min) {
  412.       corr_min=corr;
  413.       key_min=key_ptr;
  414.     }
  415.   } while (key_ptr < key_end);
  416.  
  417.   return (key_min - NB_COUPLES);
  418. }
  419.  
  420. /* the following variables are used to look at the 25 frame key
  421.    repetition. It is for information purpose only since it is not used
  422.    in the current code. */
  423.  
  424.  
  425. int decode_nagra(unsigned short *perm,
  426.                   void **lines,int xsize,int format)
  427. {
  428.   int i,j,k;
  429.   unsigned char pts_buffer[YSIZE][CX_COUNT],*p;
  430.   int corr,key;
  431.   unsigned short *correl_lines_ptr,*key_ptr;
  432.   int cx_inc,cx_start;
  433. #ifdef PROFILE
  434.   int ti=clock();
  435. #endif
  436.  
  437.   cx_inc=xsize/CX_COUNT;
  438.   cx_start=cx_inc/2;
  439.   p=&pts_buffer[0][0];
  440.  
  441.   /* preload of the pixels used for the correlation */
  442.  
  443.      if (format == 0)
  444.      {
  445.         /* 15 bits format */
  446.         for(i=0;i<YSIZE;i++) {
  447.           unsigned short *q;
  448.           q=((unsigned short **)lines)[i]+cx_start;
  449.           for(j=0;j<CX_COUNT;j+=4) {
  450.             p[0]=rgb_to_y[q[0]];
  451.             q+=cx_inc;
  452.             p[1]=rgb_to_y[q[0]];
  453.             q+=cx_inc;
  454.             p[2]=rgb_to_y[q[0]];
  455.             q+=cx_inc;
  456.             p[3]=rgb_to_y[q[0]];
  457.             q+=cx_inc;
  458.             p+=4;
  459.           }   
  460.         }
  461.     } else {
  462.         /* 32 bits format */
  463.         for(i=0;i<YSIZE;i++) {
  464.           unsigned short *q;
  465.           q=((unsigned short **)lines)[i]+cx_start;
  466.           for(j=0;j<CX_COUNT;j+=4) {
  467.             p[0]= (int)(  77.0*((unsigned char *)q)[1]    /* r */
  468.                         +150.0*((unsigned char *)q)[2]    /* g */
  469.                         + 29.0*((unsigned char *)q)[3]    /* b */
  470.                         +128.0)>>8;
  471.             q+=cx_inc*2;
  472.             p[1]= (int)(  77.0*((unsigned char *)q)[1]    /* r */
  473.                         +150.0*((unsigned char *)q)[2]    /* g */
  474.                         + 29.0*((unsigned char *)q)[3]    /* b */
  475.                         +128.0)>>8;
  476.             q+=cx_inc*2;
  477.             p[2]= (int)(  77.0*((unsigned char *)q)[1]    /* r */
  478.                         +150.0*((unsigned char *)q)[2]    /* g */
  479.                         + 29.0*((unsigned char *)q)[3]    /* b */
  480.                         +128.0)>>8;
  481.             q+=cx_inc*2;
  482.             p[3]= (int)(  77.0*((unsigned char *)q)[1]    /* r */
  483.                         +150.0*((unsigned char *)q)[2]    /* g */
  484.                         + 29.0*((unsigned char *)q)[3]    /* b */
  485.                         +128.0)>>8;
  486.             q+=cx_inc*2;
  487.             p+=4;
  488.           }   
  489.         }
  490.     }
  491.  
  492.   /* Precompute the correlation between the lines. It could be
  493.      optmized further. */
  494.   correl_lines_ptr=correl_lines;
  495.   for(i=0;i<couple_index_nb;i++) {
  496.     int v,y1,y2;
  497.     unsigned char *p1,*p2;
  498.     v=couple_index[i];
  499.     y1=v >> 9;
  500.     y2=v & 0x1ff;
  501.  
  502.     p1=&pts_buffer[y1][0];
  503.     p2=&pts_buffer[y2][0];
  504.  
  505.     corr=0;
  506.     for(k=0;k<CX_COUNT;k+=8) {
  507.       corr+=abs((int)p1[0]-(int)p2[0]);
  508.       corr+=abs((int)p1[1]-(int)p2[1]);
  509.       corr+=abs((int)p1[2]-(int)p2[2]);
  510.       corr+=abs((int)p1[3]-(int)p2[3]);
  511.       corr+=abs((int)p1[4]-(int)p2[4]);
  512.       corr+=abs((int)p1[5]-(int)p2[5]);
  513.       corr+=abs((int)p1[6]-(int)p2[6]);
  514.       corr+=abs((int)p1[7]-(int)p2[7]);
  515.       p1+=8;
  516.       p2+=8;
  517.     }
  518.     *correl_lines_ptr++=corr;
  519.   }
  520.  
  521.   key_ptr=try_perm();
  522.   key=(key_ptr - (unsigned short *)key_lines) / NB_COUPLES;
  523.  
  524.   gen_perm(perm,key);
  525.  
  526.   if (key_buf[key_buf_ptr] == key) {
  527.     key_locked='*';
  528.   } else {
  529.     key_locked=' ';
  530.   }
  531.   key_buf[key_buf_ptr++]=key;
  532.   if (key_buf_ptr == KEY_BUF_SIZE) key_buf_ptr=0;
  533.  
  534. #ifdef PROFILE
  535.   ti=clock() - ti;
  536.   fprintf(stderr,"key: %04X time=%0.3fs\n",key,
  537.           (double) ti / CLOCKS_PER_SEC);
  538. #endif
  539.  
  540.   return 0;
  541. }
  542.